/*----------------------------------------------------------------------------
Owner(s): Shane Whitfield
$Copyright: $
$Id: $
----------------------------------------------------------------------------*/

#include "go_enemies.h"
#include "timermgr.h"
#include "gomgr.h"
#include "render.h"


/*--------------------------------------------------------------------------*/
CGoSwarmer::CGoSwarmer()
{
	m_state = EState_SettingUp;
	m_tState = 0.0f;
	
	m_dps = 3.0f;
	m_dtAttackCharge = 0.3f;
	m_dtAttack = 0.2f;
	m_attackRange = 0.2f;
	m_target = NULL;
	
	SetBoundingRadius(0.03f);
	
	//load the texture of the swarmers
	SetTexture("swarmer.png");
    SetDepthLayer(EDepthLayer_GoEnemy);
}

void CGoSwarmer::Render()
{
	super::Render();
	
	if (m_state == EState_Attacking)
	{
		Color3f color(1.0f, 0.0f, 0.0f);
		BasicDrawObjects::DrawSegment(GetPos(), m_target->GetPos(), color);
	}
}

void CGoSwarmer::logState()
{
	switch (m_state)
		{
		case EState_SettingUp:
			{
				printf("EState_SettingUp\n");
			}
			break;
		case EState_HeadingToCenter:
			{
				printf("EState_HeadingToCenter\n");
			}
			break;
		case EState_WaitingForRange:
			{
				printf("EState_WaitingForRange\n");
			}
			break;
		case EState_Attacking:
			{				
				printf("EState_Attacking\n");
			}
			break;
		case EState_RechargingAttack:
			{
				printf("EState_RechargingAttack\n");
			}
			break;
		}
}

void CGoSwarmer::UpdateVelocityToCircleTarget()
{
	Vector2f velocity = m_target->GetPos() - GetPos();
					
	//simple 2d dot
	float tmp = velocity.x ;
	velocity.x = velocity.y;
	velocity.y = -tmp;
					
	SetVelocity(velocity);
	SetSpeed(1.5f);
}

void CGoSwarmer::UpdateVelocityToHeadToTarget()
{
	SetVelocity(m_target->GetPos() - GetPos());
	SetSpeed(1.5f);
	
}

void CGoSwarmer::Update()
{
	super::Update();
	
	for(;;)
	{
		//logState();
		
		EState prevState = m_state;
		switch (m_state)
		{
		case EState_SettingUp:
			{
				setState(EState_HeadingToCenter);
			}
			break;
		case EState_HeadingToCenter:
			{
				//did we find a target?
				if ((T() - m_tState) >= 0.2)
				{
					setState(EState_TargetSearch);
				}
			}
			break;
		case EState_TargetSearch:
			{
				if (m_target)
				{
					setState(EState_WaitingForRange);
				}
				else
				{
					setState(EState_HeadingToCenter);
				}
			}
			break;
		case EState_WaitingForRange:
			{				
				if (!m_target)
				{
					setState(EState_HeadingToCenter);
				}
				else if (Dist(m_target->GetPos(), GetPos()) <= m_attackRange)
				{
					setState(EState_Attacking);
				}
			}
			break;
		case EState_Attacking:
			{				
				if(!m_target)
				{
					setState(EState_HeadingToCenter);
				}
				else
				{
					UpdateVelocityToCircleTarget();
					
					//if the target is toast or our charge is out...
					// start recharging the shot
					if (!m_target || m_target->IsDead() || ((T() - m_tState) > m_dtAttack))
					{
						setState(EState_RechargingAttack);
					}
					else
					{
						m_target->Damage(m_dps*Dt());
					}
				}
			}
			break;
		case EState_RechargingAttack:
			{
				if(!m_target || m_target->IsDead())
				{
					setState(EState_HeadingToCenter);
				}
				else
				{
					UpdateVelocityToCircleTarget();
					
					//if the target is toast or our charge is out...
					// start recharging the shot
					if ((T() - m_tState) > m_dtAttackCharge)
					{
						setState(EState_Attacking);
					}
				}
			}
			break;
		}
		
		if (prevState == m_state)
		{
			break;
		}
	}
}

void CGoSwarmer::setState(EState i_state)
{
	m_state = i_state;
	m_tState = T();
	
	switch (m_state)
	{
	case EState_HeadingToCenter:
		{
			m_target = NULL;
			SetVelocity(Vector2f::Zero - GetPos());
			SetSpeed(1.5f);
		}
		break;
	case EState_WaitingForRange:
		{
			UpdateVelocityToHeadToTarget();
		}
		break;
	case EState_TargetSearch:
		{
			m_target = findTarget();
		}
		break;
	}
}

CGo* CGoSwarmer::findTarget()
{
	//get the target closest to us?
	std::vector<CGoNode*> m_foundTargets;
	g_gomgr.GetNearNodes(GetPos(), m_attackRange * 3.0f, m_foundTargets);
	
	CGo* selectedTarget = NULL;
	for (int iTarget = 0; iTarget < m_foundTargets.size(); ++iTarget)
	{
		CGo* target = m_foundTargets[iTarget];
		if (target != this && target->IsAlive())
		{
			selectedTarget = target;
			break;
		}
	}
	
	return selectedTarget;
}

/*-----------------------------------EOF!-----------------------------------*/ 
